// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// go:build linux | | freebsd | | dragonfly | | solaris 

package rand

import (
	"internal/syscall/unix"
)

// maxGetRandomRead依赖于平台。
func init() {
	altGetRandom = batched(getRandomBatch, maxGetRandomRead)
}

// batched返回一个函数，该函数调用f，通过将[]字节分块
// 到至多为readMax字节的子片中来填充它。
func batched(f func([]byte) bool, readMax int) func([]byte) bool {
	return func(buf []byte) bool {
		for len(buf) > readMax {
			if !f(buf[:readMax]) {
				return false
			}
			buf = buf[readMax:]
		}
		return len(buf) == 0 || f(buf)
	}
}

// 如果内核太旧，无法支持getrandom syscall（），
// unix。GetRandom将立即返回ENOSYS，然后我们将返回到
// 在rand_unix中读取/dev/uradom。去unix。GetRandom缓存ENOSYS 
// 结果，因此在这种情况下，我们只会承受一次系统调用开销。
// 如果内核支持getrandom（）系统调用，unix。GetRandom将阻塞
// 直到内核具有足够的随机性（因为我们不使用GRND_NONBLOCK）。
// 在本例中是unix。GetRandom不会返回错误。
func getRandomBatch(p []byte) (ok bool) {
	n, err := unix.GetRandom(p, 0)
	return n == len(p) && err == nil
}
